#include<iostream>
#include<string>
#include<cstring>
#include<time.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
#include<sys/types.h>
using namespace std;

void handler(int signo)
{
	sleep(5);
	pid_t rid;
	while((rid = waitpid(-1, nullptr, WNOHANG)) > 0)
    	cout << "process(" << getpid() << ") get a signal: " << signo << ", child process quit: " << rid << endl;
}

int main()
{
	srand(time(nullptr));
	signal(17, SIG_IGN);
	// signal(17, handler);

	for(int i = 0; i < 10; ++i)
	{
		pid_t id = fork();
		if(id == 0)
		{
			cout << "I am a child process, pid: " << getpid() << ", ppid: " << getppid() << endl;
			sleep(3);
			cout << "child process quit!\n";
			exit(0);
		}
	}
	while(1)
	{
		cout << "I am a father process, pid: " << getpid() << endl;
		sleep(1);
	}
	return 0;
}

// volatile int flag = 0;

// void handler(int signo)
// {
//     cout << "process get a signal: " << signo << endl;
// 	flag = 1;	// 跳出while循环
// }

// int main()
// {
// 	signal(2, handler);
// 	while(!flag);
// 	cout << "process quit! pid: " << getpid() << endl;
// 	return 0;
// }

// void PrintPending()
// {
// 	sigset_t pending;
// 	sigpending(&pending);
// 	for(int signo = 31; signo > 0; --signo)
// 	{
// 		if(sigismember(&pending, signo)) cout << "1";
// 		else cout << "0";
// 	}
// 	cout << "\n\n";
// }

// void handler(int signo)
// {
//     cout << "process get a signal: " << signo << endl;
// 	while(1) PrintPending(), sleep(1);
// }
// int main()
// {
// 	struct sigaction act, oact;
// 	memset(&act, 0, sizeof(act));
// 	memset(&oact, 0, sizeof(oact));

// 	// 信号捕捉处理期间自动阻塞1 3 4信号
// 	sigemptyset(&act.sa_mask);
// 	sigaddset(&act.sa_mask, 1);	 
// 	sigaddset(&act.sa_mask, 3);
// 	sigaddset(&act.sa_mask, 4);

// 	act.sa_handler = handler;
// 	sigaction(2, &act, &oact);
    
// 	while(true)
// 	{
// 		cout << "I am a child process, pid: " << getpid() << endl;
// 		sleep(1);
// 	}
// 	return 0;
// }

// int main()
// {
// 	signal(2, SIG_IGN);

// 	// 1. 先屏蔽2号信号
// 	sigset_t bset, oset;
// 	sigemptyset(&bset);
// 	sigemptyset(&oset);
// 	sigaddset(&bset, 2);	// 将2号信号添加到用户区的信号集
// 	sigprocmask(SIG_SETMASK, &bset, &oset);		//将用户定义的信号集设置到进程内核

// 	// 2. 打印 pending 
// 	sigset_t pending;
// 	int cnt = 0;
// 	while(true)
// 	{
// 		int n = sigpending(&pending);	// 获取 pending
// 		if(n == -1) continue;
// 		PrintPending(pending);
// 		sleep(1);
// 		if(++cnt == 10)
// 		{
// 			cout << "unblock 2 signo\n";
// 			sigprocmask(SIG_SETMASK, &oset, nullptr);	// 解除屏蔽
// 		}
// 	}

// 	return 0;
// }


// int main()
// {
//     pid_t id = fork();
//     if(id == 0)
//     {
//         int cnt = 500;
//         while(cnt)
//         {
//             cout << "I am a child process, pid: " << getpid() << endl;
//             sleep(1);
//             cnt--;
//         }
//         exit(0);
//     }
//     int status = 0;
//     pid_t rid = waitpid(id, &status, 0);
//     if(rid == id)
//     {
//         cout << "child quit info, rid: " << rid << ", exit code: " << ((status >> 8) & 0xFF)
//             << ", exit signal: " << ((status >> 7) & 0x7F1) << " core dump: " << ((status >> 7) & 1 ) << endl;   }
//     return 0;
// }

// void myhandler(int signo)
// {
//     cout << "process get a signal: " << signo << endl;
//     // exit(1);
//     int n = alarm(5);
//         cout << "上一次设置的闹钟的剩余时间：" << n << endl;
// }

// int main()
// {
//     signal(14, myhandler);
//     int n = alarm(50);

//     while(true)
//     {
//         cout << "I am a process, pid: " << getpid() << endl;
//         sleep(1);
//     }

//     return 0;
// }

// int main()
// {
//     signal(13, myhandler);

//     // int a = 10;
//     // a /= 0;
//     // int* p = nullptr;
//     // *p = 100;

//     char buffer[1024];
//     int n = read(4, buffer, sizeof(buffer));
//     cout << "n = " << n << endl;
//     perror("read");
//     return 0;
// }

// void Usage(string proc)
// {
//     cout << "Usage:\n\t" << proc << " signum pid\n\n";
// }


// int main(int argc, char* argv[])
// {
//     signal(SIGABRT, myhandler);  
//     int cnt = 0;
//     while(true)
//     {
//         cout << "I am a process, pid: " << getpid() << endl;
//         sleep(1);
//         // if(cnt & 1) abort();
//         // ++cnt;
//     }

//     // signal(2, myhandler);  
//     // int cnt = 0;
//     // while(true)
//     // {
//     //     cout << "I am a process, pid: " << getpid() << endl;
//     //     sleep(1);
//     //     if(cnt & 1) raise(2);   // 每两次发送一次 2 号信号
//     //     ++cnt;
//     // }

//     // if(argc != 3)
//     // {
//     //     Usage(argv[0]);
//     //     exit(1);
//     // }
//     // char* sigstr = argv[1] + 1;
//     // int signum = stoi(sigstr);
//     // pid_t pid = stoi(argv[2]);

//     // int n = kill(pid, signum);  // 调用成功返回0，失败返回-1
//     // if(n == -1) 
//     // {
//     //     perror("kill");
//     //     exit(1);    
//     // }
//     return 0;
// }



// int main()
// {
//     // signal(2, myhandler);     
//     signal(3, myhandler);     
//     // signal(19, myhandler);     
//     while(true)
//     {
//         cout << "I am a process, pid: " << getpid() << endl;
//         sleep(1);
//     }
//     return 0;
// }
